import { BadRequestException, Injectable } from '@nestjs/common';
import { InjectRepository } from '@nestjs/typeorm';
import { User } from '@/modules/user/user.entity';
import { Repository } from 'typeorm';
import { CreateUserDto } from '@/modules/user/create-user.dto';
import { Logs } from '@/modules/logs/logs.entity';
import { Menu } from '@/modules/menu/menu.entity';
import { add } from 'winston';
import { Profile } from '@/modules/user/profile.entity';

@Injectable()
export class UserService {
  constructor(
    @InjectRepository(User)
    private readonly userRepository: Repository<User>,
    @InjectRepository(Logs)
    private readonly logsRepository: Repository<Logs>,
    @InjectRepository(Profile)
    private readonly profileRepository: Repository<Profile>,
  ) {}

  // 根据ID查询用户
  async findOne(id: number) {
    let sql = `select a.*,
                      json_arrayagg(json_object(
                        'id', c.id,
                        'name', c.name
                                    )) as roles
               from admin_user a
                      left join users_roles b on b.user_id = a.id
                      left join roles c on b.role_id = c.id
               where a.id = ${id}`;

    const result = await this.userRepository.query(sql);
    if (result && result.length > 0) {
      if (result[0].id) {
        return result[0];
      }
    }
    throw new BadRequestException('User not found');
    // return this.userRepository.findOneBy({ id });
  }

  // 查询全部用户
  findAll(): Promise<User[]> {
    return this.userRepository.find();
  }

  // 新增用户
  create(createUserDto: CreateUserDto): Promise<User> {
    const user = new User();
    user.username = createUserDto.username;
    user.password = createUserDto.password;
    user.role = createUserDto.role;
    user.nickname = createUserDto.nickname;
    user.avatar = createUserDto.avatar;
    user.active = 1;
    return this.userRepository.save(user);
  }

  // 根据ID删除用户
  remove(id: number) {
    return this.userRepository.delete(id);
  }

  // 根据id更新用户信息
  async update(id, body) {
    const {
      username,
      password,
      role,
      avatar,
      nickname,
      gender,
      address,
      photo,
    } = body;
    // 更新用户数据
    let sql = `update admin_user
               set username = '${username}',
                   password = '${password}',
                   role     = '${role}',
                   avatar   = '${avatar}',
                   nickname = '${nickname}'
               where id = ${id}`;
    await this.userRepository.query(sql);
    // 更新用户profile数据
    sql = `update profile
           set gender  = '${gender}',
               address = '${address}',
               photo   = '${photo}'
           where userid = ${id}`;
    await this.profileRepository.query(sql);
    return this.findProfile(id);
  }

  // 根据用户名查询
  findByUsername(username: string) {
    return this.userRepository.findOneBy({ username });
  }

  findProfile(id: number) {
    const sql = `select a.id, a.username, a.password, b.gender, b.photo, b.address
                 from admin_user a
                        left join profile b on a.id = b.userId
                 where a.id = ${id}`;
    return this.userRepository.query(sql);
  }

  async findUserLogs(id: number) {
    // 根据用户id查询日志
    let sql = `select *
               from logs
               where userId = ${id}`;
    const logs = await this.logsRepository.query(sql);
    // 查询用户
    sql = `select a.id as userId, a.username, a.password
           from admin_user a
           where a.id = ${id}`;
    const user = await this.userRepository.query(sql);
    if (user && user.length === 1) {
      user[0].logs = logs;
      return user[0];
    }
    return null;
  }

  findLogsByGroup(id: number) {
    const sql = `
      select logs.result,
             count(logs.result) as count, json_arrayagg(json_object(
          'logId', logs.id,
          'path', logs.path,
          'method', logs.method,
          'data', logs.data
        )) as log_details
      from logs, admin_user as user
      where user.id = logs.userId and user.id = ${id}
      group by logs.result
      order by count asc`;
    return this.logsRepository.query(sql);
  }
}
